#include "common_define.h"
#include "Framework.h"
#include "Storage.h"
#include "StorageWorker.h"
#include "CToolKit.h"
#include "global.h"

using namespace std;
using namespace sdfs;

Epoll sdfs::g_client_epoll;

int main(int argc, char *argv[])
{
	if(argc != 2)
	{
		cout<<"storage [name]"<<endl;
		return 0;
	}
	bool iscontinue = true;
	epoll_event events[EPOLL_MAX_SIZE];
	char buf[10];
	struct sockaddr_in their_addr;
	unsigned int len;
	StorageWorker runner;
	cout<<argv[1]<<endl;
	Storage storage(&runner, argv[1]);
	int listenfd = storage.Start();
	Log::Debug("add listenfd:%d", listenfd);
	g_client_epoll.AddEvent(listenfd, EPOLLIN|EPOLLET);

	g_client_epoll.AddEvent(0, EPOLLIN|EPOLLET);
	Log::Debug("add keyboardfd");
	while(iscontinue)
	{
		int nfds = g_client_epoll.Wait(events, EPOLL_MAX_SIZE);
		Log::Debug("main: epoll_wait returned: %d", nfds);
		if(nfds < 0)
		{
			Log::Error("error, epoll_wait");
			continue;
		}
		for (int n = 0; n < nfds; ++n) {
			Log::Debug("main: events[%d].data.fd = %d", n, events[n].data.fd);
		     if (events[n].data.fd == listenfd) {
		    	 int new_fd = accept(listenfd, (struct sockaddr *) &their_addr,
		    	                                 &len);
		    	 if(new_fd == EWOULDBLOCK)
		    		 continue;
		    	 Log::Debug("got a connect: %d!", new_fd);
		    	 g_client_epoll.AddEvent(new_fd, EPOLLIN|EPOLLET);
		     }
		     else if(events[n].data.fd == 0)
		     {
		    	 int count = read(events[n].data.fd, buf, 10);
		    	 if(count > 0 && buf[0] == 'q'){
		    		 iscontinue = false;
		    		 g_client_epoll.DeleteEvent(events[n].data.fd);
		    		 g_client_epoll.DeleteEvent(listenfd);
		    		 continue;
		    	 }
		     }
		     else
		     {
		    	 storage.AddClient(events[n].data.fd);
		     }
		}
	}

	storage.Stop();
	return 0;
}
